<?php

namespace app\controller;

use support\Request;
use support\Response;
use app\model\User;
use app\model\RoomUser;
use app\service\FileUploadService;
use Illuminate\Database\Capsule\Manager as DB;

class UserController
{
    /**
     * 创建或更新用户
     */
    public function createOrUpdate(Request $request): Response
    {
        $data = $request->post();
        $wechatCode = $data['wechat_openid'] ?? ''; // 前端传递的是code，不是openid
        $wechatUnionid = $data['wechat_unionid'] ?? '';
        $nickname = $data['nickname'] ?? '';
        $avatar = $data['avatar'] ?? '';

        if (!$wechatCode || !$nickname) {
            return json(['success' => false, 'message' => '参数不完整']);
        }

        // 通过code换取openid
        $openidResult = $this->getOpenidByCode($wechatCode);
        if (!$openidResult['success']) {
            return json(['success' => false, 'message' => $openidResult['message']]);
        }
        
        $wechatOpenid = $openidResult['openid'];
        $wechatUnionid = $openidResult['unionid'] ?? $wechatUnionid;

        try {
            // 使用数据库事务确保用户唯一性
            $user = DB::transaction(function () use ($wechatOpenid, $wechatUnionid, $nickname, $avatar) {
                // 先尝试通过 openid 查找用户
                $user = User::where('wechat_openid', $wechatOpenid)->first();
                
                // 如果没找到且提供了 unionid，尝试通过 unionid 查找
                if (!$user && $wechatUnionid) {
                    $user = User::where('wechat_unionid', $wechatUnionid)->first();
                }
                
                if (!$user) {
                    // 创建新用户
                    $user = new User();
                    $user->wechat_openid = $wechatOpenid;
                    $user->wechat_unionid = $wechatUnionid;
                    $user->total_score = 0;
                } else {
                    // 更新现有用户的 openid 和 unionid（防止数据不一致）
                    if ($user->wechat_openid !== $wechatOpenid) {
                        $user->wechat_openid = $wechatOpenid;
                    }
                    if ($wechatUnionid && $user->wechat_unionid !== $wechatUnionid) {
                        $user->wechat_unionid = $wechatUnionid;
                    }
                }

                // 更新用户信息
                $user->nickname = $nickname;
                $user->avatar = $avatar;
                $user->save();
                
                return $user;
            });

            return json([
                'success' => true,
                'data' => [
                    'user' => [
                        'id' => $user->id,
                        'nickname' => $user->nickname,
                        'avatar' => $user->avatar,
                        'total_score' => $user->total_score,
                        'wechat_openid' => $user->wechat_openid,
                        'wechat_unionid' => $user->wechat_unionid,
                        'created_at' => $user->created_at->format('Y-m-d H:i:s')
                    ]
                ]
            ]);
        } catch (\Exception $e) {
            return json([
                'success' => false, 
                'message' => '创建或更新用户失败: ' . $e->getMessage()
            ]);
        }
    }

    /**
     * 获取用户信息
     */
    public function getInfo(Request $request): Response
    {
        $userId = $request->get('user_id');

        if (!$userId) {
            return json(['success' => false, 'message' => '用户ID不能为空']);
        }

        $user = User::find($userId);
        if (!$user) {
            return json(['success' => false, 'message' => '用户不存在']);
        }

        $userData = [
            'id' => $user->id,
            'nickname' => $user->nickname,
            'avatar' => $user->avatar,
            'total_score' => $user->total_score,
            'wechat_openid' => $user->wechat_openid,
            'created_at' => $user->created_at->format('Y-m-d H:i:s')
        ];

        return json([
            'success' => true,
            'data' => $userData
        ]);
    }

    /**
     * 获取用户房间历史
     */
    public function getRoomHistory(Request $request): Response
    {
        $userId = $request->get('user_id');

        if (!$userId) {
            return json(['success' => false, 'message' => '用户ID不能为空']);
        }

        // 暂时返回空历史，后续实现房间功能时再完善
        return json([
            'success' => true,
            'data' => [
                'history' => []
            ]
        ]);
    }

    /**
     * 更新用户总分
     */
    public function updateTotalScore(Request $request): Response
    {
        $userId = $request->post('user_id');
        $score = $request->post('score', 0);

        if (!$userId) {
            return json(['success' => false, 'message' => '用户ID不能为空']);
        }

        $user = User::find($userId);
        if (!$user) {
            return json(['success' => false, 'message' => '用户不存在']);
        }

        $user->updateTotalScore($score);

        return json([
            'success' => true,
            'data' => [
                'user' => [
                    'id' => $user->id,
                    'total_score' => $user->total_score
                ]
            ]
        ]);
    }

    /**
     * 上传头像 - 支持微信小程序新版头像API
     */
    public function uploadAvatar(Request $request): Response
    {
        $userId = $request->post('user_id');
        
        if ($userId === null || $userId === '') {
            return json(['success' => false, 'message' => '用户ID不能为空']);
        }

        // 如果是临时用户ID（0），只上传文件不更新数据库
        $isTemporaryUser = ($userId == 0);
        
        if (!$isTemporaryUser) {
            $user = User::find($userId);
            if (!$user) {
                return json(['success' => false, 'message' => '用户不存在']);
            }
        }

        // 获取上传的文件
        $file = $request->file('avatar');
        if (!$file) {
            return json(['success' => false, 'message' => '请选择头像文件']);
        }

        // 检查文件是否有效
        if (!$file->isValid()) {
            return json(['success' => false, 'message' => '上传的文件无效']);
        }

        try {
            // 使用public目录存储上传文件，更稳定且不会被清理
            $uploadDir = public_path('uploads/avatars/');
            
            // 确保上传目录存在
            FileUploadService::ensureUploadDirectory($uploadDir);

            // 生成安全的文件名
            $originalName = $file->getUploadName() ?: 'avatar';
            $extension = pathinfo($originalName, PATHINFO_EXTENSION);
            
            if ($isTemporaryUser) {
                // 临时用户使用时间戳和随机字符串
                $filename = 'avatar_temp_' . time() . '_' . uniqid();
            } else {
                // 正式用户使用用户ID
                $filename = 'avatar_' . $userId . '_' . time() . '_' . uniqid();
            }
            
            if ($extension) {
                $filename .= '.' . $extension;
            }
            $filePath = $uploadDir . $filename;

            // 移动文件 - 使用Webman框架的正确方法
            try {
                $movedFile = $file->move($filePath);
                if (!$movedFile || !file_exists($filePath)) {
                    throw new \Exception('文件移动失败');
                }
            } catch (\Exception $moveException) {
                throw new \Exception('文件移动失败: ' . $moveException->getMessage());
            }

            // 验证文件是否成功上传
            if (!file_exists($filePath)) {
                throw new \Exception('文件上传失败');
            }

            // 验证文件类型
            if (!FileUploadService::validateFileType($filePath)) {
                unlink($filePath); // 删除无效文件
                throw new \Exception('不支持的文件类型，请上传图片文件');
            }

            // 验证文件大小
            if (!FileUploadService::validateFileSize($filePath)) {
                unlink($filePath); // 删除过大文件
                throw new \Exception('文件过大，请上传小于5MB的图片');
            }

            // 生成头像URL
            $avatarUrl = '/uploads/avatars/' . $filename;
            
            if (!$isTemporaryUser) {
                // 只有正式用户才更新数据库
                $this->deleteOldAvatar($user->avatar);
                $user->avatar = $avatarUrl;
                $user->save();
                
                // 记录上传日志
                error_log("用户 {$userId} 头像上传成功: {$avatarUrl}");
            } else {
                // 临时用户只记录上传日志
                error_log("临时用户头像上传成功: {$avatarUrl}");
            }

            return json([
                'success' => true,
                'data' => [
                    'avatar_url' => $avatarUrl,
                    'message' => '头像上传成功'
                ]
            ]);
        } catch (\Exception $e) {
            // 记录错误日志
            error_log("用户 {$userId} 头像上传失败: " . $e->getMessage());
            
            return json([
                'success' => false,
                'message' => '头像上传失败: ' . $e->getMessage()
            ]);
        }
    }

    /**
     * 删除旧的头像文件
     */
    private function deleteOldAvatar($oldAvatarUrl)
    {
        if (empty($oldAvatarUrl)) {
            return;
        }

        try {
            // 如果是相对路径，转换为绝对路径
            if (strpos($oldAvatarUrl, '/') === 0) {
                $oldFilePath = public_path($oldAvatarUrl);
            } else {
                $oldFilePath = $oldAvatarUrl;
            }

            // 检查文件是否存在且不是默认头像
            if (file_exists($oldFilePath) && !strpos($oldFilePath, 'default-avatar')) {
                unlink($oldFilePath);
                error_log("删除旧头像文件: {$oldFilePath}");
            }
        } catch (\Exception $e) {
            // 删除旧文件失败不影响新文件上传
            error_log("删除旧头像文件失败: " . $e->getMessage());
        }
    }

    /**
     * 更新用户在房间中的信息
     */
    public function updateRoomInfo(Request $request): Response
    {
        $data = $request->post();
        $userId = $data['user_id'] ?? 0;
        $roomId = $data['room_id'] ?? 0;
        $nickname = $data['nickname'] ?? '';
        $avatar = $data['avatar'] ?? '';

        if (!$userId || !$roomId) {
            return json(['success' => false, 'message' => '用户ID和房间ID不能为空']);
        }

        try {
            // 更新用户基本信息
            $user = User::find($userId);
            if ($user) {
                if ($nickname) {
                    $user->nickname = $nickname;
                }
                if ($avatar) {
                    $user->avatar = $avatar;
                }
                $user->save();
            }

            // 更新房间用户表中的信息
            $roomUser = RoomUser::where('user_id', $userId)
                ->where('room_id', $roomId)
                ->first();
            
            if ($roomUser) {
                // 这里可以添加房间特定的用户信息更新
                // 比如房间内的昵称、头像等
            }

            return json([
                'success' => true,
                'message' => '房间信息更新成功',
                'data' => [
                    'user' => [
                        'id' => $user->id,
                        'nickname' => $user->nickname,
                        'avatar' => $user->avatar
                    ]
                ]
            ]);
        } catch (\Exception $e) {
            return json(['success' => false, 'message' => '更新房间信息失败：' . $e->getMessage()]);
        }
    }

    /**
     * 清理重复的微信用户（管理员功能）
     */
    public function cleanupDuplicateUsers(Request $request): Response
    {
        try {
            // 查找重复的 openid
            $duplicateOpenids = User::selectRaw('wechat_openid, COUNT(*) as count')
                ->whereNotNull('wechat_openid')
                ->where('wechat_openid', '!=', '')
                ->groupBy('wechat_openid')
                ->having('count', '>', 1)
                ->get();

            $cleanedCount = 0;
            $mergedUsers = [];

            foreach ($duplicateOpenids as $duplicate) {
                // 获取该 openid 的所有用户，按创建时间排序
                $users = User::where('wechat_openid', $duplicate->wechat_openid)
                    ->orderBy('created_at', 'asc')
                    ->get();

                if ($users->count() > 1) {
                    // 保留第一个用户，合并其他用户的数据
                    $keepUser = $users->first();
                    $otherUsers = $users->skip(1);

                    foreach ($otherUsers as $user) {
                        // 合并总分
                        $keepUser->total_score += $user->total_score;
                        
                        // 更新相关记录的用户ID
                        DB::table('accounting_records')
                            ->where('user_id', $user->id)
                            ->update(['user_id' => $keepUser->id]);
                        
                        DB::table('accounting_records')
                            ->where('target_user_id', $user->id)
                            ->update(['target_user_id' => $keepUser->id]);
                        
                        DB::table('room_users')
                            ->where('user_id', $user->id)
                            ->update(['user_id' => $keepUser->id]);
                        
                        DB::table('rooms')
                            ->where('created_by', $user->id)
                            ->update(['created_by' => $keepUser->id]);

                        // 删除重复用户
                        $user->delete();
                        $cleanedCount++;
                    }

                    $keepUser->save();
                    $mergedUsers[] = $keepUser->id;
                }
            }

            return json([
                'success' => true,
                'data' => [
                    'cleaned_count' => $cleanedCount,
                    'merged_users' => $mergedUsers,
                    'message' => "成功清理 {$cleanedCount} 个重复用户"
                ]
            ]);
        } catch (\Exception $e) {
            return json([
                'success' => false,
                'message' => '清理重复用户失败: ' . $e->getMessage()
            ]);
        }
    }

    /**
     * 通过code换取openid
     */
    private function getOpenidByCode($code)
    {
        try {
            // 获取微信小程序配置
            $wechatConfig = config('wechat.mini_program', []);
            $appId = $wechatConfig['app_id'] ?? '';
            $appSecret = $wechatConfig['secret'] ?? ''; // 注意：配置文件中是 'secret' 而不是 'app_secret'
            
            if (empty($appId) || empty($appSecret)) {
                error_log('微信小程序配置检查: app_id=' . ($appId ? '已配置' : '未配置') . ', secret=' . ($appSecret ? '已配置' : '未配置'));
                return [
                    'success' => false,
                    'message' => '微信小程序配置不完整，请检查 app_id 和 secret'
                ];
            }

            // 调用微信接口换取openid
            $url = "https://api.weixin.qq.com/sns/jscode2session";
            $params = [
                'appid' => $appId,
                'secret' => $appSecret,
                'js_code' => $code,
                'grant_type' => 'authorization_code'
            ];
            
            $response = file_get_contents($url . '?' . http_build_query($params));
            $data = json_decode($response, true);
            
            if (isset($data['errcode']) && $data['errcode'] !== 0) {
                error_log('微信接口错误: ' . json_encode($data));
                return [
                    'success' => false,
                    'message' => '获取用户信息失败: ' . ($data['errmsg'] ?? '未知错误')
                ];
            }
            
            if (!isset($data['openid'])) {
                return [
                    'success' => false,
                    'message' => '未获取到openid'
                ];
            }
            
            return [
                'success' => true,
                'openid' => $data['openid'],
                'unionid' => $data['unionid'] ?? null,
                'session_key' => $data['session_key'] ?? null
            ];
            
        } catch (\Exception $e) {
            error_log('获取openid异常: ' . $e->getMessage());
            return [
                'success' => false,
                'message' => '获取用户信息异常: ' . $e->getMessage()
            ];
        }
    }

    /**
     * 诊断用户 WebSocket 连接状态
     */
    public function diagnoseConnection(Request $request): Response
    {
        $userId = $request->get('user_id');
        
        if (!$userId) {
            return json([
                'success' => false,
                'message' => '用户ID不能为空'
            ]);
        }

        $userId = (int)$userId;
        $diagnosis = [
            'user_id' => $userId,
            'timestamp' => time(),
            'checks' => []
        ];

        try {
            // 1. 检查用户是否存在
            $user = User::find($userId);
            if (!$user) {
                return json([
                    'success' => false,
                    'message' => '用户不存在',
                    'diagnosis' => $diagnosis
                ]);
            }

            $diagnosis['user_info'] = [
                'id' => $user->id,
                'nickname' => $user->nickname,
                'avatar' => $user->avatar,
                'total_score' => $user->total_score
            ];

            // 2. 检查 Redis 中的 worker 标记
            $redis = \app\service\RedisService::getInstance();
            $userWorkerKey = "ws:user:{$userId}:worker";
            $userWorker = $redis->getClient()->get($userWorkerKey);
            
            $diagnosis['checks']['redis_worker_mark'] = [
                'key' => $userWorkerKey,
                'exists' => $userWorker !== null,
                'worker_id' => $userWorker !== null ? (int)$userWorker : null,
                'status' => $userWorker !== null ? 'found' : 'missing'
            ];

            // 3. 检查用户的房间列表（Redis）
            $userRoomsKey = "ws:user:{$userId}:rooms";
            $redisRooms = $redis->getClient()->smembers($userRoomsKey);
            
            $diagnosis['checks']['redis_rooms'] = [
                'key' => $userRoomsKey,
                'rooms' => array_map('intval', $redisRooms),
                'count' => count($redisRooms)
            ];

            // 4. 检查数据库中用户的活跃房间
            $dbRooms = RoomUser::where('user_id', $userId)
                ->where('status', RoomUser::STATUS_ACTIVE)
                ->with('room')
                ->get();
            
            $diagnosis['checks']['database_rooms'] = [
                'rooms' => $dbRooms->map(function($roomUser) {
                    return [
                        'room_id' => $roomUser->room_id,
                        'room_name' => $roomUser->room ? $roomUser->room->name : '未知',
                        'room_code' => $roomUser->room ? $roomUser->room->room_code : '未知',
                        'current_score' => $roomUser->current_score,
                        'status' => $roomUser->status,
                        'joined_at' => $roomUser->joined_at->format('Y-m-d H:i:s')
                    ];
                })->toArray(),
                'count' => $dbRooms->count()
            ];

            // 5. 检查每个房间在 Redis 中的用户集合
            $roomUsersInfo = [];
            foreach ($dbRooms as $roomUser) {
                $roomId = $roomUser->room_id;
                $roomUsersKey = "ws:room:{$roomId}:users";
                $roomUserIds = $redis->getClient()->smembers($roomUsersKey);
                
                $roomUsersInfo[] = [
                    'room_id' => $roomId,
                    'room_name' => $roomUser->room ? $roomUser->room->name : '未知',
                    'redis_key' => $roomUsersKey,
                    'users_in_redis' => array_map('intval', $roomUserIds),
                    'user_count' => count($roomUserIds),
                    'user_in_room' => in_array($userId, $roomUserIds)
                ];
            }
            
            $diagnosis['checks']['room_users_in_redis'] = $roomUsersInfo;

            // 6. 生成诊断结论和建议
            $recommendations = [];
            $issues = [];

            if (!$userWorker) {
                $issues[] = 'Redis中没有worker标记';
                $recommendations[] = '用户可能未发送connect消息，或connect消息处理失败';
                $recommendations[] = '建议前端检查WebSocket连接状态，并重新发送connect消息';
            } else {
                $recommendations[] = "用户标记在Worker {$userWorker}中，请检查该Worker进程的连接状态";
            }

            if (count($redisRooms) !== $dbRooms->count()) {
                $issues[] = 'Redis中的房间数量与数据库不一致';
                $recommendations[] = '可能需要调用refresh_rooms消息来同步房间状态';
            }

            if ($dbRooms->count() > 0 && count($redisRooms) === 0) {
                $issues[] = '数据库显示用户在房间中，但Redis中没有房间记录';
                $recommendations[] = '用户可能已连接但未正确订阅房间，建议发送refresh_rooms消息';
            }

            foreach ($roomUsersInfo as $roomInfo) {
                if (!$roomInfo['user_in_room']) {
                    $issues[] = "用户在房间{$roomInfo['room_id']}中，但Redis中没有该用户的记录";
                    $recommendations[] = "建议重新加入房间{$roomInfo['room_id']}或发送refresh_rooms消息";
                }
            }

            $diagnosis['issues'] = $issues;
            $diagnosis['recommendations'] = $recommendations;
            $diagnosis['summary'] = [
                'has_redis_worker_mark' => $userWorker !== null,
                'has_redis_rooms' => count($redisRooms) > 0,
                'has_database_rooms' => $dbRooms->count() > 0,
                'is_connected' => $userWorker !== null && count($redisRooms) > 0,
                'issue_count' => count($issues)
            ];

            return json([
                'success' => true,
                'diagnosis' => $diagnosis
            ]);

        } catch (\Exception $e) {
            return json([
                'success' => false,
                'message' => '诊断失败: ' . $e->getMessage(),
                'trace' => $e->getTraceAsString()
            ]);
        }
    }
}
